列式存储 - HBase vs Parquet

虽然两者在使用场景上没有可比性,HBase 是非关系型数据库,而 Parquet 是数据存储格式,但是两者却存在相似的概念——列式存储。我在了解 Parquet 的时候,因为列式存储这个概念与 HBase 混淆时,所以特意坐下笔记,记录两者的区别

让我们直入正题,什么是列式存储?相比行式存储又有什么优势呢?

图源来自 http://zhuanlan.51cto.com/art/201703/535729.htm


首选先从 HBase 开始讲述。HBase是一个分布式的、面向列的非关系型数据库。它的架构设计如下:

简单说明一下:

  • HMaster:HBase 主/从架构的主节点。通常在一个 HBase 集群中允许存在多个 HMaster 节点,其中一个节点被选举为 Active Master,而剩余节点为 Backup Master。其主要作用在于:
    • 管理和分配 HRegionServer 中的 Region
    • 管理 HRegionServer 的负载均衡
  • HRegionServer:HBase 主/从架构的从节点。主要负责响应 Client 端的 I/O 请求,并向底层文件存储系统 HDFS 中读写数据
  • HRegion:HBase 通过表中的 RowKey 将表进行水平切割后,会生成多个 HRegion。每个 HRegion 都会被安排到 HRegionServer 中
  • Store:每一个 HRegion 有一个或多个 Store 组成,Store 相对应表中的 Column Family(列族)。每个 Store 都由一个 MemStore 以及多个 StoreFile 组成
  • MemStore:MemStore 是一块内存区域,其将 Client 对 Store 的所有操作进行存储,并到达一定的阈值时会进行 flush 操作
  • StoreFile:MemStore 中的数据写入文件后就成为了 StoreFile,而 StoreFile 底层是以 HFile 为存储格式进行保存的
  • HFile:HBase 中 Key-Value 数据的存储格式,是 Hadoop 的二进制文件。其中 Key-Value 的格式为(Table, RowKey, Family, Qualifier, Timestamp)- Value

HBase 的主要读写方式可以通过以下流程进行:

可以从上述的架构讲述看出,HBase 并非严格意义上的列式存储,而是基于“列族”存储的,所以其是列族的角度进行列式存储。


Parquet 是面向分析型业务的列式存储格式,其不与某一特定语言绑定,也不与任何一种数据处理框架绑定在一起,其性质类似于 JSON。

Parquet 相较于 HBase 对数据的处理方式,其将数据当做成一种嵌套数据的模型,并将其结构定义为 schema。每一个数据模型的 schema 包含多个字段,而每个字段又可以包含多个字段。每一字段都有三个属性:repetition、type 和 name,其中 repetition 可以是以下三种:required(出现1次)、optional(出现0次或1次)、repeated(出现0次或多次),而 type 可以是 group(嵌套类型)或者是 primitive(原生类型)。

举一个典型的例子:

在 Parquet 格式的存储当中,一个 schema 的树结构有几个叶子节点,在实际存储中就有多少个 column。例如上面 schema 的数据存储实际上有四个 column,如下所示:

从上面的图看来,与 HBase 好像没有什么区别,但这只是为了让用户更好的了解数据才这样表示,其内部实现的机制与 HBase 完全不同,而且 Parquet 是真正的基于列式存储。其能够进行列式存储归功于 Striping/Assembly 算法。

算法我就不详细说了,这篇文章讲的很详细,我就不献丑了。


参考资料:

  1. HBase 权威指南
  2. HBase笔记:存储结构
  3. 深入分析Parquet列式存储格式